﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AddAudio2Video
{
    class AudioVideoTools
    {

        static public double getAVTimeLength(string ffmpeg, string fileName)
        {
            double second = 0;
            string fname = Path.GetFileName(fileName);
            string cmd = " -i " +  "\"" +fileName + "\"";// +"  ./" + fname;
            string result = RunCmd.RunCmdWithoutCMDWin(ffmpeg, cmd);
            //bool result = RunCmd.RunCmdWithCMDWin(this.ffmpegPath, cmd);
            //this.SetText(result);
            // Duration: 00:01:03.24, start: 0.025056, bitrate: 133 kb/s
            int b = result.IndexOf("Duration: ") + ("Duration: ").Length;
            int e = result.IndexOf(",", b);
            if (b == ("Duration: ").Length - 1 || e == -1|| e<b)
            {
                second = -1;
            }
            else
            {
                string time = result.Substring(b, e - b);
                second = toSecond(time);
            }
            return second;
        }
        static public string getAudioFormat(string ffmpeg, string fileName)
        {
            string format = "";
            string fname = Path.GetFileName(fileName);
            string cmd = " -i " +  "\"" +fileName + "\"";// +"  ./" + fname;
            string result = RunCmd.RunCmdWithoutCMDWin(ffmpeg, cmd);
            //bool result = RunCmd.RunCmdWithCMDWin(this.ffmpegPath, cmd);
            //this.SetText(result);
            // Duration: 00:01:03.24, start: 0.025056, bitrate: 133 kb/s
            int b = result.IndexOf("Audio: ") + ("Audio: ").Length;
            int e = result.IndexOf(' ', b);
            format = result.Substring(b,e-b) ;
            if (format.Contains(","))
            {
                format = format.Substring(0, format.Length - 1);
            }
            return format;

        }
        static private double toSecond(string time)
        {
            double second = 0;
            string[] tmp = time.Split(':');
            second = Convert.ToInt32(tmp[0]) * 60 * 60 + Convert.ToInt32(tmp[1]) * 60 + Convert.ToDouble(tmp[2]);

            return second;
        }

        static public bool enCodeAudio(string ffmpeg, string fromAudio, string toAudio)
        {
            bool result = true;
            string cmd = string.Format(" -y -i \"{0}\"  \"{1}\"", fromAudio, toAudio);
            string ret = RunCmd.RunCmdWithoutCMDWin(ffmpeg, cmd);
            return result;
        }
        static public bool extractAudioFromVideo(string ffmpeg,string videoPath,string audioPath)
        {
            bool result = true;
            //string cmd = string.Format(" -y -i \"{0}\" -acodec copy -vn \"{1}\"", videoPath, audioPath);
            string cmd = string.Format(" -y -i \"{0}\" -acodec copy  \"{1}\"", videoPath, audioPath);
            string ret = RunCmd.RunCmdWithoutCMDWin(ffmpeg, cmd);
            //判断是否成功
            return result;
        }
        /// <summary>
        /// get a part of one audio 
        /// </summary>
        /// <param name="ffmpeg">the path of ffmpeg</param>
        /// <param name="from">the origin audio file path</param>
        /// <param name="to">the new audio file path</param>
        /// <param name="beginTime">the begin of the new audio</param>
        /// <param name="length">the length of the new audio</param>
        /// <returns>true or false indicat success or fail</returns>
        static public bool cutAudio2Part(string ffmpeg, string from, string to, double beginTime, double length)
        {
            bool result = true;
            string cmd = string.Format(" -y -i \"{0}\" -ss {1} -t {2} -acodec copy \"{3}\"",from,beginTime,length,to);
            string ret = RunCmd.RunCmdWithoutCMDWin(ffmpeg, cmd);
            return result;
        }
        /// <summary>
        /// combain some audio files to one audio
        /// </summary>
        /// <param name="files">path audio file, need to be combined</param>
        /// <param name="to">the new audio file </param>
        /// <returns></returns>
        static public bool combineAudios21(string ffmpeg, string[] files, string fromFile, string to)
        {
            bool result = true;
            
            writeName2file(files, fromFile);
            
            //string cmd = string.Format(" -y -f concat -i \"{0}\" -c copy  \"{1}\"", fromFile, to);
            string cmd = string.Format(" -y -f concat -i \"{0}\" -ab 128k \"{1}\"", fromFile, to);
            string ret = RunCmd.RunCmdWithoutCMDWin(ffmpeg, cmd);
            //RunCmd.RunCmdWithCMDWin(ffmpeg, cmd);
            File.Delete(fromFile);
            return result;
        }

        static public bool addAudio2Video(string ffmpeg, string audio, string video, string to)
        {
            bool result = true;
            //string cmd = string.Format(" -y -i \"{0}\" -i \"{1}\" -bsf:a aac_adtstoasc -vcodec copy \"{2}\"", audio, video, to);
            string cmd = string.Format(" -y -i \"{0}\" -i \"{1}\" -acodec copy -vcodec copy \"{2}\"", audio, video, to);
            //string cmd = string.Format(" -y -i \"{0}\" -i \"{1}\" -vcodec copy \"{2}\"", audio, video, to);
            string ret = RunCmd.RunCmdWithoutCMDWin(ffmpeg, cmd);
            //RunCmd.RunCmdWithCMDWin(ffmpeg, cmd);
            return result;
        }
        static private bool writeName2file(string[] files, string fileName)
        {
            bool result = true;
            StreamWriter sw = File.CreateText(fileName);
            foreach (string name in files)
            {
                string fname = name.Replace("\\","\\\\") ;
                string line = string.Format("file {0}",fname);
                sw.WriteLine(line);
            }
            sw.Close();
            return result;
        }
        static public bool genNewAdAudio4Video(string ffmpeg, string adAudio, string null60Audio, int pos, string newAudio, string tmpPath)
        {
            bool ret = true;
            int len = pos % 60;
            string tmpNullAudio = tmpPath + "a1.mp3";
            string cmd = string.Format(" -ss 0 -i {0} -strict -2 -af atrim=0:{1} {2}",null60Audio,len,tmpNullAudio);
            RunCmd.RunCmdWithoutCMDWin(ffmpeg, cmd);
            string concat = "";
            int n = pos / 60  ;
            if (n > 0)
            {
                concat = null60Audio;
                --n;
                while (n > 0)
                {
                    concat += "|" + null60Audio;
                    --n;
                }
                concat += "|" + tmpNullAudio + "|" + adAudio;
            }
            else
            {
                concat += tmpNullAudio + "|" + adAudio ;
            }
            
            
            
            cmd = string.Format(" -i concat:\"{0}\" -vol 200 {1}", concat, newAudio);
            RunCmd.RunCmdWithoutCMDWin(ffmpeg, cmd);
            return ret;
        }
        static public bool genNewVideo(string ffmpeg, string adAudio, string adVideo, string newAdVideo, bool is264)
        {

            string cmd = string.Format(" -i {0}  -i {1} -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -vcodec libx264 -s 1280x720 -b:v 1200k  -f flv {2}",adVideo,adAudio,newAdVideo);
            if (is264 == false)
            {
                cmd = string.Format(" -i {0}  -i {1} -filter_complex amix=inputs=2:duration=first:dropout_transition=2  -f flv {2}", adVideo, adAudio, newAdVideo);
            }
            RunCmd.RunCmdWithoutCMDWin(ffmpeg, cmd);
            return true;
        }
    }
}
